<template>
  <div class="attachment-management">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <h1 class="page-title">附件管理</h1>
        <p class="page-desc">管理站点文件资源，支持图片、视频、音频和文档等多种格式</p>
      </div>
      <div class="header-right">
        <el-button type="primary" icon="Upload" @click="showUploadDialog" class="upload-btn">
          上传文件
        </el-button>
      </div>
    </div>

    <!-- 搜索筛选区域 -->
    <div class="search-section">
      <el-form :model="searchForm" inline>
        <el-form-item label="站点">
          <el-select
            v-model="searchForm.siteId"
            placeholder="选择站点"
            clearable
            style="width: 150px"
          >
            <el-option
              v-for="site in sites"
              :key="site.id"
              :label="site.name"
              :value="site.id"
            />
          </el-select>
        </el-form-item>
        
        <el-form-item label="文件类型">
          <el-select
            v-model="searchForm.mimeType"
            placeholder="选择类型"
            clearable
            style="width: 120px"
          >
            <el-option label="图片" value="image" />
            <el-option label="视频" value="video" />
            <el-option label="音频" value="audio" />
            <el-option label="文档" value="application" />
          </el-select>
        </el-form-item>
        
        <el-form-item label="文件名">
          <el-input
            v-model="searchForm.name"
            placeholder="请输入文件名"
            style="width: 200px"
            clearable
          />
        </el-form-item>
        
        <el-form-item>
          <el-button type="primary" icon="Search" @click="handleSearch">
            搜索
          </el-button>
          <el-button icon="Refresh" @click="handleReset">
            重置
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    
    <!-- 工具栏 -->
    <div class="toolbar-section">
      <div class="toolbar">
        <div class="view-mode">
          <el-radio-group v-model="viewMode" size="small">
            <el-radio-button label="grid">网格视图</el-radio-button>
            <el-radio-button label="list">列表视图</el-radio-button>
          </el-radio-group>
        </div>
        
        <div class="toolbar-actions">
          <el-button
            type="danger"
            icon="Delete"
            size="small"
            :disabled="selectedIds.length === 0"
            @click="handleBatchDelete"
          >
            批量删除
          </el-button>
        </div>
      </div>
    </div>

    <!-- 附件列表 -->
    <div class="content-section">
      <!-- 网格视图 -->
      <div v-if="viewMode === 'grid'" class="grid-view">
        <div class="attachment-grid">
          <div
            v-for="item in attachmentList"
            :key="item.id"
            class="attachment-item"
            :class="{ selected: selectedIds.includes(item.id) }"
            @click="handleItemClick(item)"
          >
            <div class="item-checkbox">
              <el-checkbox
                :model-value="selectedIds.includes(item.id)"
                @change="handleItemSelect(item.id, $event)"
                @click.stop
              />
            </div>
            
            <div class="item-preview">
              <img
                v-if="isImage(item.mimeType)"
                :src="item.url"
                :alt="item.name"
                @error="handleImageError"
              />
              <div v-else class="file-icon">
                <el-icon size="48">
                  <Document v-if="isDocument(item.mimeType)" />
                  <VideoPlay v-else-if="isVideo(item.mimeType)" />
                  <Headset v-else-if="isAudio(item.mimeType)" />
                  <Files v-else />
                </el-icon>
              </div>
            </div>
            
            <div class="item-info">
              <div class="item-name" :title="item.originalName">
                {{ item.originalName }}
              </div>
              <div class="item-meta">
                <span class="file-size">{{ formatFileSize(item.size) }}</span>
                <span class="upload-time">{{ formatDate(item.createdAt) }}</span>
              </div>
            </div>
            
            <div class="item-actions">
              <el-dropdown @command="(command) => handleCommand(command, item)">
                <el-button type="text" size="small">
                  <el-icon><MoreFilled /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="preview">预览</el-dropdown-item>
                    <el-dropdown-item command="download">下载</el-dropdown-item>
                    <el-dropdown-item command="copy">复制链接</el-dropdown-item>
                    <el-dropdown-item command="delete" divided>删除</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </div>
        </div>
      </div>
      
      <!-- 列表视图 -->
      <div v-else class="list-view">
        <el-table
          :data="attachmentList"
          v-loading="loading"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55" />
          
          <el-table-column label="预览" width="80">
            <template #default="{ row }">
              <div class="table-preview">
                <img
                  v-if="isImage(row.mimeType)"
                  :src="row.url"
                  :alt="row.name"
                  @error="handleImageError"
                />
                <el-icon v-else size="32">
                  <Document v-if="isDocument(row.mimeType)" />
                  <VideoPlay v-else-if="isVideo(row.mimeType)" />
                  <Headset v-else-if="isAudio(row.mimeType)" />
                  <Files v-else />
                </el-icon>
              </div>
            </template>
          </el-table-column>
          
          <el-table-column prop="originalName" label="文件名" min-width="200">
            <template #default="{ row }">
              <div class="file-info">
                <div class="file-name">{{ row.originalName }}</div>
                <div class="file-path">{{ row.path }}</div>
              </div>
            </template>
          </el-table-column>
          
          <el-table-column prop="mimeType" label="类型" width="120">
            <template #default="{ row }">
              <el-tag :type="getFileTypeTag(row.mimeType)" size="small">
                {{ getFileTypeText(row.mimeType) }}
              </el-tag>
            </template>
          </el-table-column>
          
          <el-table-column prop="size" label="大小" width="100">
            <template #default="{ row }">
              {{ formatFileSize(row.size) }}
            </template>
          </el-table-column>
          
          <el-table-column prop="width" label="尺寸" width="100">
            <template #default="{ row }">
              <span v-if="row.width && row.height">
                {{ row.width }} × {{ row.height }}
              </span>
              <span v-else>-</span>
            </template>
          </el-table-column>
          
          <el-table-column prop="used" label="使用状态" width="100">
            <template #default="{ row }">
              <el-tag :type="row.used ? 'success' : 'info'" size="small">
                {{ row.used ? '已使用' : '未使用' }}
              </el-tag>
            </template>
          </el-table-column>
          
          <el-table-column prop="createdAt" label="上传时间" width="160">
            <template #default="{ row }">
              {{ formatDate(row.createdAt) }}
            </template>
          </el-table-column>
          
          <el-table-column label="操作" width="150" fixed="right">
            <template #default="{ row }">
              <el-button type="text" size="small" @click="handlePreview(row)">
                预览
              </el-button>
              <el-button type="text" size="small" @click="handleDownload(row)">
                下载
              </el-button>
              <el-button
                type="text"
                size="small"
                style="color: #f56c6c"
                @click="handleDelete(row)"
              >
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      
      <!-- 分页 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="pagination.current"
          v-model:page-size="pagination.size"
          :total="pagination.total"
          :page-sizes="[20, 50, 100, 200]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>
    
    <!-- 上传对话框 -->
    <el-dialog
      v-model="uploadDialogVisible"
      title="上传文件"
      width="600px"
      @close="resetUpload"
    >
      <div class="upload-form">
        <!-- 站点选择 -->
        <el-form :model="uploadForm" label-width="80px">
          <el-form-item label="目标站点" required>
            <el-select
              v-model="uploadForm.siteId"
              placeholder="请选择上传到哪个站点"
              style="width: 100%"
            >
              <el-option
                v-for="site in sites"
                :key="site.id"
                :label="site.name"
                :value="site.id"
              >
                <span style="float: left">{{ site.name }}</span>
                <span style="float: right; color: #8492a6; font-size: 13px">
                  {{ site.domain }}
                </span>
              </el-option>
            </el-select>
          </el-form-item>
        </el-form>
      </div>

      <div class="upload-container">
        <el-upload
          ref="uploadRef"
          class="upload-dragger"
          drag
          multiple
          :action="uploadAction"
          :headers="uploadHeaders"
          :data="uploadData"
          :before-upload="beforeUpload"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :file-list="fileList"
          :auto-upload="false"
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">
            将文件拖到此处，或<em>点击上传</em>
          </div>
          <template #tip>
            <div class="el-upload__tip">
              支持 jpg/png/gif/pdf/doc/xls 等格式，单个文件不超过 200MB（图片自动压缩为WebP格式）
            </div>
          </template>
        </el-upload>
      </div>
      
      <template #footer>
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleUpload" :loading="uploading">
          开始上传
        </el-button>
      </template>
    </el-dialog>
    
    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      :title="previewFile?.originalName"
      width="800px"
    >
      <div class="preview-container" v-if="previewFile">
        <img
          v-if="isImage(previewFile.mimeType)"
          :src="previewFile.url"
          :alt="previewFile.name"
          class="preview-image"
        />
        <video
          v-else-if="isVideo(previewFile.mimeType)"
          :src="previewFile.url"
          controls
          class="preview-video"
        />
        <audio
          v-else-if="isAudio(previewFile.mimeType)"
          :src="previewFile.url"
          controls
          class="preview-audio"
        />
        <div v-else class="preview-info">
          <el-icon size="64"><Files /></el-icon>
          <p>{{ previewFile.originalName }}</p>
          <p>文件大小: {{ formatFileSize(previewFile.size) }}</p>
          <p>文件类型: {{ previewFile.mimeType }}</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, computed } from 'vue'
import { ElMessage, ElMessageBox, type UploadInstance } from 'element-plus'
import { validateGeneralFile, formatFileSize, FILE_SIZE_LIMITS } from '@/config/upload'
import { attachmentApi } from '@/api/attachment'
import { siteApi } from '@/api/site'
import { useUserStore } from '@/stores/user'
import type { Attachment, Site } from '@/types/api'

const userStore = useUserStore()

const loading = ref(false)
const viewMode = ref<'grid' | 'list'>('grid')
const selectedIds = ref<number[]>([])
const uploadDialogVisible = ref(false)
const previewDialogVisible = ref(false)
const uploading = ref(false)
const uploadRef = ref<UploadInstance>()
const fileList = ref([])
const previewFile = ref<Attachment>()

// 上传表单
const uploadForm = reactive({
  siteId: null as number | null
})

// 站点数据
const sites = ref<Site[]>([])

// 搜索表单
const searchForm = reactive({
  siteId: undefined as number | undefined,
  name: '',
  mimeType: '',
})

// 附件列表
const attachmentList = ref<Attachment[]>([])

// 分页信息
const pagination = reactive({
  current: 1,
  size: 20,
  total: 0,
})

// 上传配置 - 使用Light CMS
const uploadAction = computed(() => {
  if (uploadForm.siteId) {
    return `/cms/admin/attachment/upload/${uploadForm.siteId}`
  }
  return '/cms/admin/attachment/upload'
})

const uploadHeaders = computed(() => ({
  Authorization: `Bearer ${userStore.token}`,
}))

const uploadData = computed(() => ({
  siteId: uploadForm.siteId || searchForm.siteId || 1,
  userId: userStore.userInfo?.id || 1,
}))

// 获取站点列表
const getSites = async () => {
  try {
    const response = await siteApi.getSiteTree()
    sites.value = response.data
  } catch (error) {
    console.error('获取站点列表失败:', error)
  }
}

// 获取附件列表
const getAttachmentList = async () => {
  try {
    loading.value = true
    const response = await attachmentApi.getAttachmentPage({
      current: pagination.current,
      size: pagination.size,
      ...searchForm,
    })
    attachmentList.value = response.data.records
    pagination.total = response.data.total
  } catch (error) {
    console.error('获取附件列表失败:', error)
  } finally {
    loading.value = false
  }
}

// 处理搜索
const handleSearch = () => {
  pagination.current = 1
  getAttachmentList()
}

// 处理重置
const handleReset = () => {
  Object.assign(searchForm, {
    siteId: undefined,
    name: '',
    mimeType: '',
  })
  pagination.current = 1
  getAttachmentList()
}

// 处理项目点击
const handleItemClick = (item: Attachment) => {
  const index = selectedIds.value.indexOf(item.id)
  if (index > -1) {
    selectedIds.value.splice(index, 1)
  } else {
    selectedIds.value.push(item.id)
  }
}

// 处理项目选择
const handleItemSelect = (id: number, checked: boolean) => {
  if (checked) {
    if (!selectedIds.value.includes(id)) {
      selectedIds.value.push(id)
    }
  } else {
    const index = selectedIds.value.indexOf(id)
    if (index > -1) {
      selectedIds.value.splice(index, 1)
    }
  }
}

// 处理选择变更
const handleSelectionChange = (selection: Attachment[]) => {
  selectedIds.value = selection.map(item => item.id)
}

// 处理命令
const handleCommand = (command: string, item: Attachment) => {
  switch (command) {
    case 'preview':
      handlePreview(item)
      break
    case 'download':
      handleDownload(item)
      break
    case 'copy':
      handleCopyLink(item)
      break
    case 'delete':
      handleDelete(item)
      break
  }
}

// 处理预览
const handlePreview = (item: Attachment) => {
  previewFile.value = item
  previewDialogVisible.value = true
}

// 处理下载
const handleDownload = (item: Attachment) => {
  const link = document.createElement('a')
  link.href = item.url
  link.download = item.originalName
  link.click()
}

// 处理复制链接
const handleCopyLink = async (item: Attachment) => {
  try {
    await navigator.clipboard.writeText(item.url)
    ElMessage.success('链接已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 处理删除
const handleDelete = (item: Attachment) => {
  ElMessageBox.confirm(`确定要删除文件"${item.originalName}"吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(async () => {
    try {
      const response = await attachmentApi.deleteAttachment(item.id)
      if (response.code === 0) {
        ElMessage.success('删除成功')
        getAttachmentList()
      } else {
        ElMessage.error(response.msg || '删除失败')
      }
    } catch (error: any) {
      console.error('删除附件失败:', error)
      ElMessage.error(error.response?.data?.msg || error.message || '删除失败')
    }
  })
}

// 处理批量删除
const handleBatchDelete = () => {
  ElMessageBox.confirm(`确定要删除选中的 ${selectedIds.value.length} 个文件吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(async () => {
    try {
      const response = await attachmentApi.batchDeleteAttachments(selectedIds.value)
      if (response.code === 0) {
        ElMessage.success('批量删除成功')
        selectedIds.value = []
        getAttachmentList()
      } else {
        ElMessage.error(response.msg || '批量删除失败')
      }
    } catch (error: any) {
      console.error('批量删除失败:', error)
      ElMessage.error(error.response?.data?.msg || error.message || '批量删除失败')
    }
  })
}

// 显示上传对话框
const showUploadDialog = () => {
  // 设置默认站点（如果当前有筛选站点，则使用筛选的站点）
  uploadForm.siteId = searchForm.siteId || (sites.value.length > 0 ? sites.value[0].id : null)
  uploadDialogVisible.value = true
}

// 上传前检查
const beforeUpload = (file: File) => {
  // 使用统一的文件验证
  const validation = validateGeneralFile(file)
  if (!validation.valid) {
    ElMessage.error(validation.error!)
    return false
  }
  return true
}

// 处理上传
const handleUpload = () => {
  // 验证是否选择了站点
  if (!uploadForm.siteId) {
    ElMessage.warning('请选择目标站点')
    return
  }

  // 验证是否有文件
  if (!fileList.value || fileList.value.length === 0) {
    ElMessage.warning('请选择要上传的文件')
    return
  }

  uploadRef.value?.submit()
}

// 上传成功
const handleUploadSuccess = (response: any, file: any) => {
  if (response.code === 0) {
    ElMessage.success('上传成功')
    // Light CMS的上传接口已经自动保存到数据库，直接刷新列表
    getAttachmentList()
  } else {
    ElMessage.error('上传失败：' + (response.msg || '未知错误'))
  }
}

// 上传失败
const handleUploadError = (error: any) => {
  console.error('上传失败:', error)
  ElMessage.error('上传失败')
}

// 重置上传
const resetUpload = () => {
  fileList.value = []
  uploadRef.value?.clearFiles()
  uploadForm.siteId = null
}

// 处理分页大小变更
const handleSizeChange = (size: number) => {
  pagination.size = size
  pagination.current = 1
  getAttachmentList()
}

// 处理当前页变更
const handleCurrentChange = (current: number) => {
  pagination.current = current
  getAttachmentList()
}

// 判断是否为图片
const isImage = (mimeType: string) => {
  return mimeType.startsWith('image/')
}

// 判断是否为视频
const isVideo = (mimeType: string) => {
  return mimeType.startsWith('video/')
}

// 判断是否为音频
const isAudio = (mimeType: string) => {
  return mimeType.startsWith('audio/')
}

// 判断是否为文档
const isDocument = (mimeType: string) => {
  return mimeType.startsWith('application/') || mimeType.startsWith('text/')
}

// 获取文件类型标签
const getFileTypeTag = (mimeType: string) => {
  if (isImage(mimeType)) return 'success'
  if (isVideo(mimeType)) return 'primary'
  if (isAudio(mimeType)) return 'warning'
  return 'info'
}

// 获取文件类型文本
const getFileTypeText = (mimeType: string) => {
  if (isImage(mimeType)) return '图片'
  if (isVideo(mimeType)) return '视频'
  if (isAudio(mimeType)) return '音频'
  if (isDocument(mimeType)) return '文档'
  return '其他'
}

// formatFileSize 已从 @/config/upload 导入

// 格式化日期
const formatDate = (dateString: string) => {
  return new Date(dateString).toLocaleString('zh-CN')
}

// 处理图片错误
const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.style.display = 'none'
}

onMounted(() => {
  getSites()
  getAttachmentList()
})
</script>

<style scoped lang="scss">
.attachment-management {
  padding: 24px;
  background: #f8f9fa;
  min-height: 100vh;

  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 24px;
    padding: 24px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

    .header-left {
      .page-title {
        font-size: 24px;
        font-weight: 600;
        color: #2c3e50;
        margin: 0 0 6px 0;
      }

      .page-desc {
        font-size: 14px;
        color: #6c757d;
        margin: 0;
      }
    }

    .header-right {
      .upload-btn {
        height: 40px;
        padding: 0 20px;
        font-size: 14px;
        font-weight: 500;
        border-radius: 6px;
      }
    }
  }

  .search-section {
    margin-bottom: 20px;
    padding: 20px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  }
  
  .toolbar-section {
    margin-bottom: 20px;
    padding: 20px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);

    .toolbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
  }

  .content-section {
    background: white;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    overflow: hidden;
  }
  
  .grid-view {
    .attachment-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: 16px;
      
      .attachment-item {
        position: relative;
        border: 1px solid #e4e7ed;
        border-radius: 8px;
        padding: 12px;
        cursor: pointer;
        transition: all 0.3s;
        
        &:hover {
          border-color: #409eff;
          box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
        }
        
        &.selected {
          border-color: #409eff;
          background-color: #f0f9ff;
        }
        
        .item-checkbox {
          position: absolute;
          top: 8px;
          left: 8px;
          z-index: 1;
        }
        
        .item-preview {
          height: 120px;
          display: flex;
          align-items: center;
          justify-content: center;
          background: #f5f7fa;
          border-radius: 4px;
          margin-bottom: 8px;
          
          img {
            max-width: 100%;
            max-height: 100%;
            object-fit: cover;
          }
          
          .file-icon {
            color: #909399;
          }
        }
        
        .item-info {
          .item-name {
            font-size: 14px;
            font-weight: 500;
            color: #303133;
            margin-bottom: 4px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }
          
          .item-meta {
            font-size: 12px;
            color: #909399;
            display: flex;
            justify-content: space-between;
          }
        }
        
        .item-actions {
          position: absolute;
          top: 8px;
          right: 8px;
        }
      }
    }
  }
  
  .list-view {
    .table-preview {
      width: 48px;
      height: 48px;
      display: flex;
      align-items: center;
      justify-content: center;
      
      img {
        max-width: 100%;
        max-height: 100%;
        object-fit: cover;
        border-radius: 4px;
      }
    }
    
    .file-info {
      .file-name {
        font-weight: 500;
        margin-bottom: 4px;
      }
      
      .file-path {
        font-size: 12px;
        color: #909399;
      }
    }
  }
  
  .pagination-wrapper {
    display: flex;
    justify-content: center;
    margin-top: 20px;
  }
  
  .upload-container {
    .upload-dragger {
      width: 100%;
    }
  }
  
  .preview-container {
    text-align: center;
    
    .preview-image {
      max-width: 100%;
      max-height: 500px;
    }
    
    .preview-video {
      max-width: 100%;
      max-height: 400px;
    }
    
    .preview-audio {
      width: 100%;
    }
    
    .preview-info {
      padding: 40px;
      color: #909399;
      
      p {
        margin: 8px 0;
      }
    }
  }
}
</style>
